/*
 * ColaBloqueante.h
 *
 *  Esta cola tiene la novedad de que es thread safe. Es decir, se protege a si
 *  misma de que mas de un hilo actue sobre ella simultaneamente
 */

#ifndef COLABLOQUEANTE_H_
#define COLABLOQUEANTE_H_

#include <queue>
#include <iostream>
#include "Lock.h"

template <class T>
class ColaBloqueante {
	std::queue<T> cola;
	Mutex mutex;

	public:
		ColaBloqueante<T>(){}
		virtual ~ColaBloqueante<T>(){}

		// Devuelve el elemento correspondiente y lo elimina de la pila
		T pop(){
			Lock lock(this->mutex);

			// La cola esperara hasta que haya al menos un elemento
			while (this->cola.empty()) {
				lock.wait();
			}
			T elem = this->cola.front();
			this->cola.pop();
			return elem;
		}

		void push(const T elem){
			Lock lock(this->mutex);
			this->cola.push(elem);
			// Cuando alguien pushea, avisa al que esta esperando que ya puede popear
			lock.signal();
		}

		bool vacia(){
			Lock lock(this->mutex);
			return (this->cola.empty());
		}
};

#endif
